package de.mnit.basis.daten.struktur.ordnen.algo;

import de.mnit.basis.daten.konstant.VERHAELTNIS;
import de.mnit.basis.daten.struktur.ordnen.S_Sortierbar;
import de.mnit.basis.daten.typ.Vergleich;
import de.mnit.basis.fehler.Fehler;
import de.mnit.basis.sys.Ausgabe;

/**
 * @author Michael Nitsche
 */
public abstract class A_SortierAlgo implements S_SortierAlgo {

	public final void sortieren(S_Sortierbar<?> tab, int... nach) {
		Fehler.objekt.wenn_Null(tab);
		if(nach==null || nach.length==0)
			nach=new int[]{1};
		for(int i : nach)
			Fehler.zahl.wenn_Ausserhalb(1,tab.gBreite(),Math.abs(i));

		if(nach.length>10)
			Ausgabe.warnung("Das Limit der Breite von 10 wird mit "+nach.length+" überschritten!");
		if(tab.gLaenge()>100000)
			Ausgabe.warnung("Das Limit der Länge von 100000 wird mit "+tab.gLaenge()+" überschritten!");

		sortieren2(tab,nach);
	}

	protected abstract void sortieren2(S_Sortierbar<?> tab, int... nach);


	protected boolean schwerer(S_Sortierbar<?> tab, int zeile, int als_zeile, int... nach) {
		return verhaeltnis(tab, zeile, als_zeile, nach)==VERHAELTNIS.IST_GROESSER;
	}

	protected VERHAELTNIS verhaeltnis(S_Sortierbar<?> tab, int zeile1, int zeile2, int... nach) {
		VERHAELTNIS erg=VERHAELTNIS.IST_GLEICH;
		for(int nachpos=0; erg==VERHAELTNIS.IST_GLEICH && nach.length>nachpos; nachpos++) {
			int n=Math.abs(nach[nachpos]);
			Object o1=tab.gib(n, zeile1);
			Object o2=tab.gib(n, zeile2);
			if(Vergleich.istGleich(o1,o2))
				erg = VERHAELTNIS.IST_GLEICH;
			else {
				boolean ig=Vergleich.istGroesser(o1,o2);
				if(nach[nachpos]<0)
					ig=!ig;
				erg = ig ? VERHAELTNIS.IST_GROESSER : VERHAELTNIS.IST_KLEINER;
			}
		}
		return erg;
	}

}
